﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Redis.Core
{
    /// <summary>
    /// Redis Hash对象
    /// </summary>
    public class RedisHash : RedisBase
    {
        public RedisHash(Manager manager, String HashName)
            : base(manager.GetClient())
        {
            Name = HashName;
        }

        public RedisHash(String HashName)
            : base(Manager.Default.GetClient())
        {
            Name = HashName;
        }
        public RedisHash()
            : base(Manager.Default.GetClient())
        {
            timeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
        }

        public bool Exist(String key)
        {
            return Redis.HashContainsEntry(Name, key);
        }

        public bool IsExist
        {
            get
            {
                return Redis.ContainsKey(Name);
            }
        }

        public bool Remove(String key)
        {
            return Redis.RemoveEntryFromHash(Name, key);
        }

        public bool Delete()
        {
            return Redis.Remove(Name);
        }


        
        public bool SetValueIfNotExists<T>(string HashName, string key, T Item)
        {
            var value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            return Redis.SetEntryInHashIfNotExists(HashName, key, value);
        }


        public bool SetValue<T>(string HashName, string key, T Item)
        {
            var value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            return Redis.SetEntryInHash(HashName, key, value);
        }

        public bool SetValue<T>(String key, T Item)
        {
            if (String.IsNullOrEmpty(Name))
            {
                throw new Exception("未为Hash指定Name");
            }
            var value = JsonConvert.SerializeObject(Item, Formatting.None, timeConverter);
            return Redis.SetEntryInHash(Name, key, value);
        }

        public T GetValue<T>(String key)
        {
            if (String.IsNullOrEmpty(Name))
            {
                throw new Exception("未为Hash指定Name");
            }
            string value = Redis.GetValueFromHash(Name, key);
            return JsonConvert.DeserializeObject<T>(value);
        }

        public T GetValue<T>(string HashName, string key)
        {
            string value = Redis.GetValueFromHash(HashName, key);
            return JsonConvert.DeserializeObject<T>(value);
        }


        public List<T> GetValues<T>(string HashName)
        {
            var result = new List<T>();
            var list = Redis.GetHashValues(HashName);
            if (list != null && list.Count > 0)
            {
                list.ForEach(x =>
                {
                    var value = JsonConvert.DeserializeObject<T>(x);
                    result.Add(value);
                });
            }
            return result;
        }

        public List<T> GetValues<T>(params String[] keys)
        {
            var result = new List<T>();
            var list = Redis.GetValuesFromHash(Name, keys);
            if (list != null && list.Count > 0)
            {
                list.ForEach(x =>
                {
                    var value = JsonConvert.DeserializeObject<T>(x);
                    result.Add(value);
                });
            }
            return result;
        }

        public IDictionary<String, T> GetKeyValues<T>(params String[] keys)
        {
            var result = new Dictionary<String, T>();
            var list = Redis.GetValuesFromHash(Name, keys);
            for (int i = 0; i < keys.Length; i++)
            {
                T def = default(T);
                if (list[i] != null)
                {
                    def = JsonConvert.DeserializeObject<T>(list[i]);
                }
                result[keys[i]] = def;
            }
            return result;
        }



        public Int64 Increment(string key, Int32 incrementBy)
        {
            return Redis.IncrementValueInHash(Name, key, incrementBy);
        }

        public Int64 Decrement(string key, Int32 incrementBy)
        {
            return Redis.IncrementValueInHash(Name, key, -incrementBy);
        }


        public List<String> GetKeys()
        {
            return Redis.GetHashKeys(Name);
        }



        public List<String> GetValues()
        {
            return Redis.GetHashValues(Name);
        }




        public Dictionary<string, string> GetKeyValues()
        {
            return Redis.GetAllEntriesFromHash(Name);
        }



        public Int64 Count
        {
            get
            {
                return Redis.GetHashCount(Name);
            }
        }


        public TimeSpan GetTimeToLive()
        {
            return Redis.GetTimeToLive(Name);
        }


        /// <summary>
        /// 设置缓存过期
        /// </summary>
        public void SetExpire(string key, DateTime datetime)
        {
            Redis.ExpireEntryAt(key, datetime);
        }




        public String Name { get; set; }

        private static Newtonsoft.Json.Converters.IsoDateTimeConverter timeConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter()
        {
            DateTimeFormat = "yyyy-MM-dd HH:mm:ss ffff"
        };
    }
}
